<?php
/*
header("Content-type: text/html; charset=utf-8");
define('DB_DSN', 'my_sql:dbname=kaixin001;host=my_sql.13zi.com');
define('DB_USERNAME', 'hejunbin');
define('DB_PASSWORD', 'jj123456');
define('DB_DEBUG', true);
*/

//error_reporting(0);

class CDb {

	//private static $_singleton = null;
	private static $_instances;
	private $_conn;
	private $_sth;
    protected $lastSql;
    public $tablePrefix = 'kiss_';

	private function __construct() {
		//echo 
		try {
			$this->_conn = new PDO('mysql:dbname=kisscms;host=localhost', 'root', '');
			$this->_conn->query('SET NAMES utf8');
		} catch (PDOException $e) {
			echo '<pre>';
			echo '<b>Connection failed:</b> ' . $e->getMessage();
			//echo '</pre>';
			die();
		}

	}

    public static function getInstance($id = 'main')
    {
        if (empty(self::$_instances[$id])) {
            self::$_instances[$id] = new CDb();
        }
        return self::$_instances[$id];
    }


	
	function halt($msg = '', $sql = '') {

		$error_info = $this->_sth->errorInfo();
		$s = '<pre>';
		$s .= '<b>Error:</b>'.$error_info[2].'<br />';
		$s .= '<b>Errno:</b>'.$error_info[1].'<br />';
		$s .= '<b>Sql:</b>'.$this->lastSql;
		//$s .= '</pre>';
		exit($s);

	}

	function execute($sql, $params = array()) {
		$this->lastSql = $this->parseSql($sql, $params);
		$this->_sth = $this->_conn->prepare($sql);
		$bool = $this->_sth->execute($params);
		//echo "sdf";
		
		if('00000' !== $this->_sth->errorCode()) {
			/*
			echo '<pre>';
			echo $this->_sql . '<br />';
			print_r($this->_conn->errorInfo());
			echo '</pre>';
			die();
			*/
			$this->halt();
		}

		return $bool;

	}

	function getAll($sql, $params = array(), $fetch_style = PDO::FETCH_ASSOC) {

		//$_conn = $this->query($sql, $data);
		//return (false !== $_conn) ? $_conn->fetchAll() : false;
		//$_conn = $this->prepare($sql);
		//$_conn->execute($data);
		$this->execute($sql, $params);
		return $this->_sth->fetchAll($fetch_style);

	}

	function getRow($sql, $params = array(), $fetch_style = PDO::FETCH_ASSOC) {
/*
        if ($limited == true)
			$sql = trim($sql . ' LIMIT 1');
*/
/*
        $_conn = $this->query($sql, $data);
        if ($_conn !== false) {
            $row = $_conn->fetch();
			return (false !== $row) ? $row : '' ;
        } else {
			return false;
        } 
*/
		//$_conn = $this->prepare($sql);
		//$_conn->execute($data);
		$this->execute($sql, $params);
		return $this->_sth->fetch($fetch_style);

	}

	function getOne($sql, $params = array(), $column_number = 0) {
/*
		$_conn = $this->query($sql, $data);
		return (false !== $_conn) ? $_conn->fetchColumn() : false;        
*/
		//$_conn = $this->prepare($sql);
		//$_conn->execute($data);
		$this->execute($sql, $params);
		return $this->_sth->fetchColumn($column_number);

	}


	function insert($table, $data) {
		
		$fields = array_keys($data);
		$marks = array_fill(0, count($fields), '?');

		$sql = "INSERT INTO $table (`" . implode('`,`', $fields) . "`) VALUES (".implode(", ", $marks)." )";
		return $this->execute($sql, array_values($data));
		
	}

	function insertId() {
		return $this->_conn->lastInsertId();
	}	
	
	function update($table, $data, $where) {

		/*
		$fields = array_keys($data);
		$_conn = $this->prepare( "UPDATE $table SET " . implode( ' = ?, ', $fields ) . ' = ? WHERE ' . $where );
		return $_conn->execute(array_values($data));
*/

        $params = $bits = $wheres = array();
        foreach ( $data as $k=>$v ) {
            $bits[] = "`$k` = ?";
			$params[] = $v;
		}
 
        //if ( is_array( $where ) )
            foreach ( $where as $c => $v ) {                
				$wheres[] = "$c = ?";
				$params[] = $v;
			}
        //else
            //return false;

		//$_conn = $this->prepare( "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ) );
		//return $_conn->execute($params);

        //return $this->query( "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ) . ' LIMIT 1' );

		$sql = "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
		return $this->execute($sql, $params);

	}

    public function parseSql($sql, $params = array()) {
        $count = count($params);
        if ($count > 0) {
            $sql = str_replace('?', '%s', $sql);
            for ($i = 0; $i < $count; $i++) {
                $params[$i] = $this->quote($params[$i]);
            }
            array_unshift($params, $sql);
            $this->lastSql = call_user_func_array('sprintf', $params);
        } else {
            $this->lastSql = $sql;
        }
        return $this->lastSql;
    }

    public function quote($param) {
    	return $this->_conn->quote($param);
    }
}
